﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.Reflection;
using System.ComponentModel;
//using System.Reflection;
using Microsoft.Xna.Framework;
using System.Windows.Forms;
using Microsoft.Xna.Framework.Content;
using System.Collections;
using System.Data;

namespace FormaBedoboNS
{
    /// <summary>
    /// Alkalmazás beállításait tartalmazó osztály
    /// </summary>
    [Serializable]
    public class AppSettings
    {

        private static AppSettings _instance = null;

        private string content = "Content";

        string assemblyLocation = Assembly.GetExecutingAssembly().Location;
        string fbxPath, levelsPath;
        /// <summary>
        /// melyik nyelvet használjuk épp
        /// </summary>
        public static string language{get; set;}

        /// <summary>
        /// van-e hanglejátszó eszköz
        /// </summary>
        [XmlIgnore]
        public bool soundHW { get; set; }

        /// <summary>
        /// Content mappa neve
        /// </summary>
        public string ContentRootDirectory { get; set; }

        /// <summary>
        /// Content mappa útvonala
        /// </summary>
        public string path { get; set; }
        /// <summary>
        /// 
        /// </summary>
        [XmlIgnore]
        public ContentBuilder contentBuilder{ get; set; }
        /// <summary>
        /// ez kezeli a betöltött ikonokat
        /// </summary>
        [XmlIgnore]
        public ContentManager contentManager{ get; set; }
        /// <summary>
        /// ez kezeli a modellek Content-et
        /// </summary>
        [XmlIgnore]
        public ContentManager contentManager1 { get; set; }

        /// <summary>
        /// A szintek tárolója
        /// </summary>
        public Dictionary<int, Level> Levels = new Dictionary<int, Level>();

        /// <summary>
        /// aktuális szint a játékban
        /// </summary>
        public int currentLevel { get; set; }
        /// <summary>
        /// aktuális user, aki játszik
        /// </summary>
        public string currentUser { get; set; }

        private static GameDataSet _gameDataSet;
        /// <summary>
        /// az adatok tárolója, adatbázis
        /// </summary>
        public GameDataSet gameDataSet
        {
            get
            {
                return _gameDataSet;
            }
        }

        /// <summary>
        /// az AppSettings példánya
        /// </summary>
        public static AppSettings instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new AppSettings();

                }

                return _instance;
            }
        }

        /// <summary>
        /// Konstruktor
        /// </summary>
        public AppSettings()
        {
            _gameDataSet = new FormaBedoboNS.GameDataSet();
            // 
            // gameDataSet
            // 
            _gameDataSet.DataSetName = "GameDataSet";
            _gameDataSet.SchemaSerializationMode = System.Data.SchemaSerializationMode.IncludeSchema;
            ((System.ComponentModel.ISupportInitialize)(_gameDataSet)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(_gameDataSet)).EndInit();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="i"></param>
        public void KinectElevation(int i)
        {
            DataRow r = _gameDataSet.Tables["Kinect"].Rows[0];
            r.SetField<int>("elevation", i);
        }
        /// <summary>
        /// Kinect fej aktuális emelési mértékét kapjuk meg
        /// </summary>
        /// <returns></returns>
        public int GetKinectElevation()
        {
            DataRow r = _gameDataSet.Tables["Kinect"].Rows[0];
            return r.Field<int>("elevation");
        }
        /// <summary>
        /// a játékszint idejét írja a felhasználó táblába
        /// </summary>
        /// <param name="u"></param>
        /// <param name="t"></param>
        public void setLevelTime(string u, TimeSpan t)
        {
            DataRow r=_gameDataSet.Tables["users"].Rows.Find(u);
            r.SetField<TimeSpan>(currentLevel, t);
        }
        /// <summary>
        /// FBX folder: runtime content build
        /// </summary>
        public void ContentBuild()
        {

            IDictionary environmentVariables = Environment.GetEnvironmentVariables();
            //foreach (DictionaryEntry de in environmentVariables)
            //    {
            //    Console.WriteLine("  {0} = {1}", de.Key, de.Value);
            //    }
            string env;
            if (Environment.Is64BitOperatingSystem)
                env="ProgramFiles(x86)";
            else
                env="ProgramFiles";
            if (!File.Exists(environmentVariables[env] + "\\MSBuild\\Microsoft\\XNA Game Studio\\" +
                            "v4.0\\Microsoft.Xna.GameStudio.ContentPipeline.targets"))
            {
                MessageBox.Show(AppSettings.getString("XNA Studio 4.0"), AppSettings.getString("error"));
                return;
            }
            //Cursor = Cursors.WaitCursor;
            Console.WriteLine(AppSettings.getString("Modellek feldolgozása elkezdődött..."));
            contentManager.Unload();

            contentBuilder.Clear();

            string ss = Path.GetFullPath(fbxPath + "/");
            foreach (KeyValuePair<int, Level> pair in Levels)
            {
                foreach (string file in pair.Value.files)
                {
                    string s2 = Path.GetFileNameWithoutExtension(file);
                    contentBuilder.Add(ss + pair.Value.name+"/"+file+".fbx", pair.Value.name + "_" + file, null, "ModelProcessor"); 
                }

            }
 
            string buildError = contentBuilder.Build();
            Console.WriteLine(AppSettings.getString("Modellek feldolgozása befejeződött."));
            //Cursor = Cursors.Arrow;

            if (!string.IsNullOrEmpty(buildError))
            {
                Console.WriteLine(buildError);
                MessageBox.Show(AppSettings.getString("fbxerror"), AppSettings.getString("fbxerrortitle"));
            }

        }

        /// <summary>
        /// egy nyelvi sztringet kérünk
        /// </summary>
        public static string getString(string id)
        {
            string ret = "";
            try { 
                ret=_gameDataSet.Tables["language"].Rows.Find(id).Field<string>(language);
            }
            catch(Exception){
                ret=id;
            }
            return ret;
        }

        /// <summary>
        /// adatok HDD-re írása
        /// </summary>
        public static void adatKiiras()
        {
            try
            {
                _gameDataSet.WriteXml("../../../../config/gameData.xml");

                //XmlSerializer serializer;
                //TextWriter WriteFileStream;
                //serializer = new XmlSerializer(typeof(AppSettings));
                //WriteFileStream = new StreamWriter(instance.path + instance.fileName, false);
                //serializer.Serialize(WriteFileStream, instance);
                //WriteFileStream.Close();


            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }

        /// <summary>
        ///  HDD-ről adatok olvasása
        /// </summary>
        public void adatfelolvasas()
        {
            try
            {
                _gameDataSet.ReadXml("../../../../config/gameData.xml");
            }
            catch (Exception e)
            { 
                Console.WriteLine("Wrong gameData.xml");
                Console.WriteLine(e.Message);
                Console.WriteLine("Application will exit, press any key to continue...");
                Console.ReadKey();
                Environment.Exit(-2);
            }
            ContentRootDirectory = content;
            path = "data\\";
            levelsPath = Path.Combine(assemblyLocation, "../../../../../config/Levels.xml");
            fbxPath = Path.Combine(assemblyLocation, "../../../../../fbx");
            int i=0;
            foreach (DataRow row in _gameDataSet.Tables["levels"].Rows) // Loop over the rows.
            {
                i++;
                Level l = new Level();
                l.name = row.Field<string>("name");
                l.foldername = row.Field<string>("foldername");
                l.files = new List<string>();
                Levels.Add(i,l);
            }

            if (i != 0)
                currentLevel = 1;

            Console.WriteLine("Alkalmazás beállítások beolvasása");


            foreach (KeyValuePair<int, Level> pair in Levels)
            {
                string ss = Path.GetFullPath(fbxPath + "/" + pair.Value.foldername);
                if (Directory.Exists(ss))
                {
                    string[] fileEntries = Directory.GetFiles(ss);
                    pair.Value.files.Clear();
                    foreach (string fileName in fileEntries)
                    {
                        string s2 = Path.GetFileNameWithoutExtension(fileName);
                        //contentBuilder.Add(fileName, pair.Value.name + "_" + Path.GetFileNameWithoutExtension(fileName), null, "ModelProcessor");
                        string ext = Path.GetExtension(fileName);
                        if (ext.ToLower() == ".fbx")
                        pair.Value.files.Add(Path.GetFileNameWithoutExtension(fileName));
                    }
                }

                else
                {
                    Console.WriteLine("{0} is not a valid file or directory.", pair.Value.foldername);
                }

            }

            contentBuilder = new ContentBuilder();

            //Level l = new Level();
            //l.name = "level1";
            //l.foldername = "level1";
            //Levels.Add("1", l);
            //l = new Level();
            //l.name = "level2";
            //l.foldername = "level2";
            //Levels.Add("2", l);
        }

       
        /// <summary>
        /// Leírással rendelkező enumok esetén a leírást kéri el.
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public string GetEnumDescription(Enum value)
        {
            FieldInfo fi = value.GetType().GetField(value.ToString());

            DescriptionAttribute[] attributes =
                (DescriptionAttribute[])fi.GetCustomAttributes(
                typeof(DescriptionAttribute),
                false);

            if (attributes != null &&
                attributes.Length > 0)
                return attributes[0].Description;
            else
                return value.ToString();
        }
    }
}
